﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tao.FreeGlut;
using Tao.OpenGl;
using Tao.Platform.Windows;
using System.Threading;
using VoxelEngine;

namespace VoxelGame
{
    public partial class Form1 : Form
    {
        World W = new World();
        float angle = 0.0f;
        public Form1()
        {
            InitializeComponent();
            AnT.InitializeContexts();
            InitializeGL();
            ResizeGlScene();
        }

        private void ResizeGlScene()
        {
            // Предупредим деление на нуль;
            if (AnT.Height == 0)
            {
                AnT.Height = 1;
            }
            // Сбрасываем текущую область просмотра;
            Gl.glViewport(0, 0, AnT.Width, AnT.Height);
            // Выбираем матрицу проекций;
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            // Сбрасываем выбранную матрицу;
            Gl.glLoadIdentity();
            // Вычисляем новые геометрические размеры сцены;
            Glu.gluPerspective(45.0f,
                (float)AnT.Width / (float)AnT.Height,
                0.1f, 100.0f);
            // Выбираем матрицу вида модели;
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            // Сбрасываем ее;
            Gl.glLoadIdentity();
        } 

        private void InitializeGL()
        {
            /*Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_RGB|Glut.GLUT_DOUBLE|Glut.GLUT_DEPTH);
            Gl.glShadeModel(Gl.GL_SMOOTH);
            Gl.glClearColor(1.0f, 1.0f, 1.0f, 0.5f);
            Gl.glClearDepth(1.0f);
            Gl.glEnable(Gl.GL_DEPTH_TEST);
            Gl.glDepthFunc(Gl.GL_LEQUAL);
            Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);
            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glLightModelf(Gl.GL_LIGHT_MODEL_TWO_SIDE, Gl.GL_TRUE);
            Gl.glEnable(Gl.GL_NORMALIZE);*/
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
            Gl.glShadeModel(Gl.GL_SMOOTH);
            Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_NICEST);
            Gl.glClearColor(255, 255, 255, 1);
            Gl.glViewport(0, 0, AnT.Width, AnT.Height);

            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Glu.gluPerspective(45, (float)AnT.Width / (float)AnT.Height, 0.1, 200);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
            Gl.glEnable(Gl.GL_DEPTH_TEST);
            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glLightModelf(Gl.GL_LIGHT_MODEL_TWO_SIDE, Gl.GL_TRUE);
            Gl.glEnable(Gl.GL_NORMALIZE);
            /*Gl.glEnable(Gl.GL_BLEND);
            // Устанавливаем тип смешивания;
            Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);*/
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            /*

            

            DateTime Start = DateTime.Now;*/
            
            System.Windows.Forms.Timer T = new System.Windows.Forms.Timer();
            //T.Interval = 1;
            T.Tick += (sender1, e1) =>
                {
                    Draw();
                };
            T.Start();
        }

        private void LightInit()
        {
            //float[] light0_diffuse = { 0.0f, 0.0f, 0.0f};
            float[] light0_direction = { 1.0f, 0.0f, 2.0f, 0.0f};

            Gl.glEnable(Gl.GL_LIGHT0);
            //Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, light0_diffuse);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, light0_direction);
        }

        private void Draw()
        {
            angle++;
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
            Gl.glLoadIdentity();

            LightInit();

            //Gl.glTranslatef(0.0f, 0.0f, -7.0f);
            
            /*float[] color1 = {0.6f, 0.6f, 0.6f};
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, color1);*/
            //Gl.glTranslatef(0.0f, 0.0f, -5.0f);
            /*Gl.glNormal3f(0.0f, 0.0f, -1.0f);*/
            //Gl.glRotatef(25.0f, 1.0f, 1.0f, 1.0f);
            /*Glut.glutSolidCube(1);

            float[] color2 = { 1.0f, 0.0f, 0.0f };
            Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, color2);
            Gl.glTranslatef(1.0f, 0.0f, 0.0f);
            Gl.glNormal3f(0.0f, 0.0f, -1.0f);
            Glut.glutSolidCube(1);*/
            Boolean RotStop = false;
            foreach (Voxel V in W.VoxelList)
            {
                float[] materialColor = { (float)V.VoxelColor.R/255.0f, (float)V.VoxelColor.G/255.0f, (float)V.VoxelColor.B/255.0f};
                Gl.glMaterialfv(Gl.GL_FRONT,Gl.GL_DIFFUSE, materialColor);
                Gl.glTranslatef(V.Offset.X, V.Offset.Y, V.Offset.Z-10.0f);
                //Gl.glTranslatef(0.0f, 0.0f, -5.0f);
                Gl.glNormal3f(0.0f, 0.0f, 1.0f);
                if (!RotStop)
                {
                    Gl.glRotatef(115.0f, 1.0f, 1.0f, 1.0f);
                }
                Glut.glutSolidCube(1);
                RotStop = true;
            }

            //Gl.glRotatef(25.0f, 1.0f, 1.0f, 1.0f);
            AnT.Invalidate();
            /*Gl.glEnable(Gl.GL_MULTISAMPLE_ARB);
            

            Gl.glLoadIdentity();
            Gl.glColor3f(0.0f, 0.8f, 0.8f);
            Gl.glPushMatrix();
            Gl.glTranslated(0, 0, -6);
            

            //Glut.glutWireSphere(2, 32, 32);
            Gl.glNormal3f(0.0f, 0.0f, -1.0f);
            Gl.glEnable(Gl.GL_LINE_SMOOTH);
            //Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_FASTEST);
            
            

            Gl.glPopMatrix();
            Gl.glFlush();
            */

        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            ResizeGlScene();
        }
    }
}
